perm filename DOER[AP,SYS]4 blob
sn#018556 filedate 1973-01-05 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00015 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 Definitions.
C00007 00003 Flag definitions and storage allocations.
C00012 00004 Start of main program (DOER). Prepare to read in uncataloged story from 'NEWS' file.
C00017 00005 Read in undun story. Check sequence nbr for digest, etc.
C00021 00006 For each word in story, collect its letters.
C00024 00007 Check current word for indicator of a correction, an add, or a take.
C00030 00008 Find appropriate place in sorted list for current word.
C00034 00009 Open INDEX and DICT files. Read in WORDS and LINKS files.
C00036 00010 Look for keywords in story. Link up any that are found.
C00039 00011 Link up keyword in story.
C00045 00012 Write out new versions of files.
C00050 00013 Subroutines: RDDICT, GTDICT, PAUSE1-4, DIGEST, DONTDO, GONE.
C00055 00014 Subroutines: UUCODE.
C00060 00015 Interrupt level module: INTRPT, CHGNAM.
C00065 ENDMK
C⊗;
;Definitions.
TITLE DOER
EXTERNAL JOBAPR,JOBCNI
; ACCUMULATOR ASSIGNMENTS
F←←0 ;contains flags in LH and "@" (octal 100) in RH
A←1 ;temporary AC
B←2 ;temporary AC
C←3 ;temporary AC
AVAIL←←3 ;pointer to an available link block in LINKS
WD←4 ;the word being looked at in the sorted list
PREV←←4
D←4 ;AC for the number of a detected error
DICTWD←5 ;pointer to the current dictionary entry
FIRST←6 ;ptr to text of current dictionary word
AC1←←7 ;temporary AC
AC2←←10 ;temporary AC
SORPTR←7 ;pointer to current entry in the sorted list (SORDID)
TXTPTR←10 ;byte pointer for depositing letters into TEXT area
PART1←←11 ;four ac's for holding the (possible) 4 words per
PART2←←12 ; entry in the sorted list. Used in comparison.
PART3←←13
PART4←←14
CHAR←11 ;current character of story
DISPL←12
SIZE←13
BPTR←15 ;byte pointer into buffer holding current story
LWD←16 ;the last word looked at in the sorted list
P←17
LF←←12 CR←←15
NKEYS←←=20 ;max nbr of keywords all starting with same word
PDLEN←←=30 ;length of push down list
SPECS←←4 ;number of special words at front of INDEX file
XSIZE←←3 ;size of the index entry for one story
MAXNBR←←=500 ;maximum number of stories allowed
XLEN←MAXNBR*XSIZE+SPECS ;total size of space for index entries
LLEN←←10000
WLEN←←6400
DEFINE UNDUN {INDEX} ;first word in INDEX file
DEFINE NEW {INDEX+1} ;second word
DEFINE OLD {INDEX+2} ;third word
LOC 41
JSR UUCODE
LOC
OPDEF UEXIT [001000,,];minor error. swap in new version of DOER
OPDEF UERROR [002000,,];moderate error. write message in ERRORS file and swap
OPDEF UBIGERR [003000,,];horrendous error. write message in ERRORS file
;Flag definitions and storage allocations.
;LEFT HALF FLAGS (AC 0)
LESS ← 400000 ; used when looking for an earlier story with given seq nbr
WRFLAG← 200000 ; 1 if the DICREC must be written out
MISSIN← 100000 ; 1 if story sought in NEWS was not found
TAKEFG←← 40000 ; 1 if current story is a TAKE
CATFLG←← 20000 ; 1 if current word has been used to categorize the story
NEWSF: SIXBIT /NEWS/ ;block for LOOKUP and ENTER for NEWS file
BLOCK 3
INDEXF: SIXBIT /INDEX/ ;block for LOOKUP and ENTER for INDEX file
BLOCK 3
LINKSF: SIXBIT /LINKS/ ;block for LOOKUP and ENTER for LINKS file
BLOCK 3
DICTF: SIXBIT /DICT/ ;block for LOOKUP and ENTER for DICT file
BLOCK 3
WORDSF: SIXBIT /WORDS/ ;block for LOOKUP for WORDS file
BLOCK 3
ERRORF: SIXBIT /ERRORS/;block for LOOKUP and ENTER for ERRORS file
BLOCK 3
BUF: ;buffer to hold part of ERRORS file is same as STORY buffer
STORY: BLOCK 2200 ;buffer to hold stories
INDEX: BLOCK XLEN ;core array for holding index pointers for stories
LINKS: BLOCK LLEN ;holds the assorted relationships for words found in DICT
DICT: BLOCK 400 ;holds two records of the dictionary, 1 reg and 1 mults
WORDS: BLOCK WLEN ;holds the words actually pointed to in DICT
SORDID: BLOCK =600 ;holds the sorted list of words in a story
TEXT: BLOCK =1500 ;holds the characters of the words in the story
PDLIST: BLOCK PDLEN ;push down list
KEYS: BLOCK NKEYS ;ptrs to dictionary entries for keywords categorizing story
CMD: IOWD 1,STORY ;command for reading in a story to be cataloged
0
XCMD: IOWD XLEN,INDEX ;command for reading/writing INDEX
0
LCMD: IOWD LLEN,LINKS ;command for reading/writing LINKS
0
DCMD: IOWD 200,DICT ;command for reading/writing DICT
0
MCMD: IOWD 200,DICT+200 ;command for reading/writing a mult rec of DICT
0
WCMD: IOWD WLEN,WORDS ;command for reading WORDS
0
DSK17: 217 ;block for OPENing the DSK in mode 17 many times
SIXBIT /DSK/ ;200 bit means take error return automatically
0 ; if DISK IS FULL or BAD RETRIEVAL
SWAPBK: SIXBIT /DSK/
SIXBIT /DOER/
SIXBIT /DMP/
1 ;start at 1 past normal starting address
SIXBIT / APSYS/
NAME: SIXBIT /[DOER]/ ;name DOER uses while running
WRDCNT: 0
DICPTR: 0 ;pointer to the current dictionary entry
DICREC: 0 ;number of the current record of DICT that is in core
MLTPTR: 0 ;negated ptr to DICT entry for current mult word key
MLTREC: 0 ;number of the current mult rec of DICT that is in core
GUDREC: 0 ;number of current mult rec that needs to be in core
LKOVFL: 0 ;LINKS space overflow flag
LOSEQ: 0 ;lowest acceptable seq nbr for earlier take
HISEQ: 0 ;highest acceptable seq nbr for earlier take
SPBPTR: 0 ;special byte ptr
NRDOER: 0 ;code indicating number of other DOERs
TTYLIN: 0 ;word for indicating whether DOER is detached
STCNT: 0 ;word for number of stories we have yet to look for earlier take
LEN: 0 ;pseudo length of a story word
CHCNT: 0 ;character count for the UNDUN story
CATNBR: 0 ;nbr of similar keywords categorizing story
;Start of main program (DOER). Prepare to read in uncataloged story from 'NEWS' file.
DOER: SKIPA ;normal starting address leaves RESTART = 0
SETOM RESTAR# ;if swapped in by self, set RESTAR = -1
MOVEI F,"@" ;clear all flags in LH, and load "@" in RH
MOVEI A,INTRPT ;get address of interrupt level module
MOVEM A,JOBAPR ;store it in JOBAPR
MOVE A,[400200000] ;enable for interrupts on parity errors and
CALL A,[SIXBIT /INTENB/]; pdl ov
MOVEI A,200000
CALL A,[SIXBIT /INTGEN/];generate a pdl ov interrupt to set the job name
MOVE A,NRDOER ;get code nbr indicating number of other DOERs
JRST .+2(A)
UBIGERR 4 ; ;ONE OTHER DOER ALREADY EXISTS!
UBIGERR 10 ; ;TWO OR MORE DOERS ALREADY EXIST!
AGAIN3: OPEN 1,DSK17 ;get the index file
UERROR 14 ; ;OPEN FAILED ON DSK
SETZM INDEXF+3
LOOKUP 1,INDEXF ;INDEX file
JRST PAUSE3
IN 1,XCMD ;read in INDEX file
JRST .+2
UERROR 20 ; ;IN UUO FAILED TO READ IN INDEX FILE
RELEAS 1, ;INDEX file
MOVE P,[INITPD: IOWD PDLEN,PDLIST];init the stack ptr
MOVE B,UNDUN ;grab UNDUN from the INDEX file
MORE: CAMN B,NEW ;has UNDUN caught up with NEW?
CALL [SIXBIT /EXIT/] ;yes. exit (releasing the job since jlog is probably not set)
;check if UNDUN points to a story that has been deleted or otherwise wiped out
DOMORE: MOVE A,OLD ;get index of OLD story and compare with
CAMG A,NEW ; index of NEW area
JRST OLDLES ;OLD index is above (less than) NEW index
CAML B,NEW ;NEW index is above (less than) OLD index.
CAML B,OLD ;is UNDUN between OLD and NEW?
JRST DOMOR1 ;no. everything is ok.
OLDUN: MOVEM A,UNDUN ;make the oldest story the first undun one
MOVE B,A
JRST DOMOR1
OLDLES: CAML B,OLD ;OLD index is above (less than) NEW index
CAML B,NEW ;is UNDUN between OLD and NEW?
JRST OLDUN ;no! UNDUN story seems to have been deleted (or something)
;calculate the size of the UNDUN story using its position and that of the next story
DOMOR1: MOVE SIZE,B
ADDI SIZE,XSIZE
CAIL SIZE,XLEN
MOVEI SIZE,SPECS
MOVN SIZE,INDEX+1(SIZE)
ADD SIZE,INDEX+1(B)
JUMPL SIZE,ONWARD
DOWN: MOVN SIZE,INDEX+3 ;UNDUN story is last in NEWS. get ptr to end of NEWS
ADD SIZE,INDEX+1(B)
ONWARD: ASH SIZE,-13 ;right adjust the negated size of the UNDUN story
OUTSTR [ASCIZ / STORY! /]
HRRZ DISPL,INDEX+1(B);get displacement of UNDUN story
ASH DISPL,-13 ;right-adjust displacement
MOVN A,DISPL ;make displacement negative (size is already negative)
ADD A,SIZE ;calculate length of NEWS stuff to be read in
HRLM A,CMD ;put length in the command word
SETZM LINKS+1 ;clear the back ptr to slots for this story
TLZ F,TAKEFG+MISSIN ;clear these two flags
;Read in undun story. Check sequence nbr for digest, etc.
AGAIN1: OPEN 0,DSK17 ;prepare to read the NEWS file
UERROR 24 ; ;OPEN FAILED ON DSK
SETZM NEWSF+3
LOOKUP 0,NEWSF ;NEWS file
JRST PAUSE1 ;can't read NEWS...FILER is writing it
HLRZ A,INDEX+1(B) ;get record number for UNDUN story
USETI 0,(A)
IN 0,CMD ;input the UNDUN story into STORY
JRST .+2
UERROR 30 ; ;IN UUO FAILED TO READ IN NEWS STORY
RELEAS 0, ;NEWS file
MOVEI BPTR,STORY-1(DISPL) ;point byte pointer at first word of story
HRLI BPTR,700 ;initialize byte pointer
MOVE TXTPTR,[POINT 7,TEXT-1,34] ;initialize byte ptr to start of TEXT
MOVE A,SIZE ;put number of chars in story into CNT by
ASH A,2 ; multiplying size by 5
ADD A,SIZE
MOVEM A,CHCNT ;store number of chars
MOVEI SORPTR,1 ;initialize SORPTR to start of SORDID
MOVEI B,3 ;prepare to look for 3 digits of sequence nbr
SETZ C,
NEXTDG: ILDB A,BPTR ;get a char from first word of story
CAIG A,"9" ;is it a digit?
CAIGE A,"0"
JRST GONE ;no!
IMULI C,=10 ;yes. multiply sum of previous digits by =10
ADDI C,-60(A) ;add in current digit
SOJG B,NEXTDG ;got all 3 digits of seq nbr?
ILDB A,BPTR ;yes. get char after the 3 digits
CAIE A,CR ;does CR follow the digits?
JRST GONE ;no!
ILDB A,BPTR ;yes
CAIE A,LF ;does LF follow the CR?
JRST GONE ;no!
MOVE B,UNDUN
HRRZ A,INDEX+2(B) ;GET SUPPOSED SEQ NBR OF STORY
CAME C,A ;DOES STORY IN NEWS HAVE CORRECT SEQ NBR?
JRST GONE ;NO!
MOVEM C,HISEQ ;SAVE SEQ NBR OF CURRENT STORY
JUMPE C,DONTDO ;dont categorize stories 000 and 001
CAIN C,1
JRST DONTDO
CAIE C,=200 ;dont categorize stories 200 and 201
CAIN C,=201
JRST DONTDO
CAIE C,2 ;is this the PMS digest (story 002)?
CAIN C,=202 ;is this the AMS digest (story 202)?
JRST DIGEST ;yes to one of these
;For each word in story, collect its letters.
MOVEI A,=45 ;number of words at the front of the story that
MOVEM A,WRDCNT ; are checked for special meanings
SETZM SORDID ;zero the header for the sorted list
BETW: AOSLE CHCNT ;begin reading characters until a letter is hit or
JRST READ ; there are no more characters
ILDB CHAR,BPTR ;get next character from story
CAIL CHAR,"A"
JRST LTR
CAIL CHAR,"0" ;character is not a letter
CAILE CHAR,"9" ;is it a digit?
JRST BETW ;no
JRST CONT ;yes
LTR2: TRZ CHAR,40 ;make all letters upper case
JRST MIDDL
LTR: TRZ CHAR,40 ;make all letters upper case
CONT: MOVEM TXTPTR,SORDID(SORPTR);store byte ptr to TEXT of this new word
MIDDL: IDPB CHAR,TXTPTR ;deposit this letter in TEXT
AOSLE CHCNT ;any more chars in story?
JRST DEP100 ;no
ILDB CHAR,BPTR ;yes, get one
CAIL CHAR,"A"
JRST LTR2 ;it's a letter
CAIGE CHAR,"0" ;it's not a letter
JRST DEP100 ;nor a digit
CAIG CHAR,"9"
JRST MIDDL ;it is a digit and the word goes on
DEP100: IDPB F,TXTPTR ;end of word...fill out text word with @'s
TLNE TXTPTR,760000
JRST DEP100
HRRZ A,SORDID(SORPTR);get ptr to beginning of current word
MOVE PART1,1(A) ;move word to PARTS for comparison for sorting
MOVE PART2,2(A)
MOVE PART3,3(A)
MOVE PART4,4(A)
;Check current word for indicator of a correction, an add, or a take.
SOSGE WRDCNT ;is current word among first words of story?
JRST ON ;no
CAMN PART1,[ASCII /TAKES/] ;is story the first of several takes?
JRST [TLO F,TAKEFG ;yes. mark it so
JRST ON]
CAMN PART1,[ASCII /TAKE@/] ;is story possibly a take of an earlier story?
JRST TAKE ;yes
TDNE PART1,[372010040000] ;is current word possibly a seq nbr?
JRST ON ;no
SETCA PART1, ;yes
TDNE PART1,[405406030000] ;check appropriate bits for 1's
JRST [SETCA PART1, ;not a seq nbr. re-complement PART1 back
JRST ON] ; to normal and go on
SETCA PART1,
;is a seq nbr.
LDB B,[POINT 7,PART1,13] ;AC B WILL HOLD THE REFERENCED SEQ NBR IN BINARY
SUBI B,60 ;CONVERT 1ST DIGIT TO BINARY FROM ASCII
IMULI B,=10
LDB C,[POINT 7,PART1,20]
ADDI B,-60(C) ;ADD IN 2ND DIGIT OF SEQ NBR
IMULI B,=10
LDB C,[POINT 7,PART1,27]
ADDI B,-60(C) ;ADD IN 3RD DIGIT OF SEQ NBR
MOVE PREV,UNDUN ;prepare to look up index entry for prev story
TLZ F,LESS
CAMGE B,HISEQ ;does earlier story have smaller seq nbr?
TURNON: TLO F,LESS ;yes
NXPREV: CAMN PREV,OLD ;have we gotten back to oldest story?
JRST ON ;yes. give up search
SUBI PREV,XSIZE ;no. get index of the previous story
CAIGE PREV,SPECS
MOVEI PREV,XLEN-XSIZE
HRRZ C,INDEX+2(PREV) ;GET SEQ NBR OF THIS PREVIOUS STORY
CAMN B,C ;IS THE PREV STORY THE ONE REFERRED TO?
JRST LINKEM ;yes!
CAIGE B,=500 ;is current story a special story?
CAIL C,=500 ;is prev story a special story?
JRST NXPREV ;one of them is. dont make termination test
CAMG B,C ;have we passed seq nbr of desired story?
JRST TURNON ;no. we are headed for it now
TLNN F,LESS ;yes. were we ever headed for it?
JRST NXPREV ;no. keep searching
JRST ON ;yes. give up the search
LINKEM: OPEN 7,DSK17 ;grab INDEX file
UERROR 34 ; ;OPEN FAILED ON DSK
SETZM INDEXF+1
SETZM INDEXF+2
SETZM INDEXF+3
ENTER 7,INDEXF
JRST [RELEAS 7,
MOVEI A,2
CALL A,[SIXBIT /SLEEP/]
JRST LINKEM]
JRST FINISH
TAKE: MOVEM BPTR,SPBPTR ;copy the (byte) ptr into the story
TAK1: ILDB CHAR,SPBPTR ;get next char from story
CAIN CHAR,"t" ;is it a "t" (as in "two")?
JRST TAK9
CAIL CHAR,"A" ;is it a letter?
JRST ON
CAIL CHAR,"0" ;no.
CAILE CHAR,"9" ;is it a digit?
JRST TAK1 ;no. get next char
TAK9: MOVE PREV,UNDUN ;yes. we have, eg: take 2
TLO F,TAKEFG ;set take flag in case cant find original take
HRREI A,-6 ;number of stories back we are willing
MOVEM A,STCNT ; to look for the earlier take
ADD A,HISEQ
MOVEM A,LOSEQ ;SAVE MIN SEQ NBR WE CAN ACCEPT FOR EARLIER TAKE
TAK8: SUBI PREV,XSIZE ;get index of the previous story
CAIGE PREV,SPECS ; so that we can link current
MOVEI PREV,XLEN-XSIZE ; story with the previous one,
HRRZ A,INDEX+2(PREV) ; which should be an earlier
CAML A,LOSEQ ; take of the same story.
CAMLE A,HISEQ ;IS SEQ NBR OF THIS PREV STORY IN RIGHT RANGE?
JRST GETNXT ;NO. GET NEXT PREV STORY.
HRRE C,INDEX(PREV) ;YES. IS THIS PREV STORY A TAKE?
AOJE C,LINKEM ;IF SO, LINK UP TO THE CURRENT STORY
GETNXT: AOSGE STCNT ;HAVE WE EXAMINED LIMIT OF PREV STORIES?
JRST TAK8 ;NO. TRY THE NEXT PREV STORY.
;Find appropriate place in sorted list for current word.
ON: MOVE A,SORDID(SORPTR);retrieve byte ptr into TEXT for current word
SUB A,TXTPTR ;get length of word
HRLM A,SORDID(SORPTR);save length of this word
CAMGE A,[-4] ;is word longer than 20 letters?
HRREI A,-4 ;yes. ignore all but first 20 letters
MOVEM A,LEN ;save pseudo length of this word (max = 4)
SETZ LWD, ;LWD points to the last examined word in the list
NEXT: HLRZ WD,SORDID(LWD) ;get pointer from LWD to next WD
TRZ WD,700000 ;zero out length bits that were in the pointer
JUMPE WD,INSERT ;if null pointer, insert word at end of list
HRRZ FIRST,SORDID(WD);get pointer from WD to text (characters) of word
MOVE A,LEN ;load A with length of current word (in words)
CAME PART1,1(FIRST) ;method of comparison: compare first parts.
JRST CHECK1 ; If unequal, jump out. Otherwise, if
AOJGE A,INSERT ; there is still part of the word left,
CAME PART2,2(FIRST) ; continue comparing.If the word is the
JRST CHECK2 ; same as an existing word, go to INSERT to
AOJGE A,INSERT ; insert it again.
CAME PART3,3(FIRST)
JRST CHECK3
AOJGE A,INSERT
CHECK4: CAMG PART4,4(FIRST) ;note that we only need one CAM for the last part (PART4)
JRST INSERT
JRST ADVNCE
CHECK3: CAMG PART3,3(FIRST) ;if it is greater, then you want to continue checking.
JRST INSERT ;if it is less, you want to insert it where you are
JRST ADVNCE ;advance the pointers.
CHECK2: CAMG PART2,2(FIRST)
JRST INSERT
JRST ADVNCE
CHECK1: CAMG PART1,1(FIRST)
JRST INSERT
ADVNCE: MOVE LWD,WD ;the new LWD is the old WD
JRST NEXT ;continue down list looking for place to insert current word
;insert next word into list of previously sorted words.
INSERT: HLRZ A,SORDID(SORPTR);retrieve the size of current word
ASH A,17 ;move the size to the left hand bits of AC right
ADD A,WD ;put the link in the low order bits of AC right
HRLM A,SORDID(SORPTR);store the length and link of the new word
HLRZ A,SORDID(LWD) ;get the length and link of LWD
TRZ A,77777 ;zero the link
ADD A,SORPTR ;add in the new link
HRLM A,SORDID(LWD) ;store the length and new link of LWD
ADDI SORPTR,1 ;increment SORPTR to next word not yet sorted
JRST BETW
;Open INDEX and DICT files. Read in WORDS and LINKS files.
READ: OPEN 7,DSK17 ;prepare to open INDEX for writing new version
UERROR 40 ; ;OPEN FAILED ON DSK
SETZM INDEXF+1
SETZM INDEXF+2
SETZM INDEXF+3
ENTER 7,INDEXF ;INDEX file
JRST PAUSE2 ;FILER must be writing INDEX now...wait a bit
AGAIN4: OPEN 3,DSK17 ;open DICT file in Read Alter mode
UERROR 44 ; ;OPEN FAILED ON DSK
SETZM DICTF+3
LOOKUP 3,DICTF
JRST PAUSE4
SETZM DICTF+1
SETZM DICTF+2
SETZM DICTF+3
ENTER 3,DICTF
JRST PAUSE4
SETZM DICREC ;indicate that no DICT rec is in core
SETZM MLTREC ;indicate that no mult rec of DICT is in core
SETOM CATNBR
PUSHJ P,GTDICT
OPEN 4,DSK17 ;read in WORDS
UERROR 50 ; ;OPEN FAILED ON DSK
SETZM WORDSF+3
LOOKUP 4,WORDSF
UERROR 54 ; ;LOOKUP FAILED ON FILE: WORDS
IN 4,WCMD
JRST .+2
UERROR 60 ; ;IN UUO FAILED TO READ IN FILE: WORDS
RELEAS 4,
OPEN 5,DSK17 ;read in LINKS
UERROR 64 ; ;OPEN FAILED ON DSK
SETZM LINKSF+3
LOOKUP 5,LINKSF
UERROR 70 ; ;LOOKUP FAILED ON FILE: LINKS
IN 5,LCMD
JRST .+2
UERROR 74 ; ;IN UUO FAILED TO READ IN FILE: LINKS
RELEAS 5,
;Look for keywords in story. Link up any that are found.
SETZM LINKS+1 ;init back ptr from new story to LINKS
SETZ WD, ;point to header of sorted list
MOVEI DICTWD,2 ;point to first word in dictionary
MOVEM DICTWD,DICPTR
NEXTWD: TLZ F,CATFLG ;clear the "categorized" flag
HLRZ WD,SORDID(WD) ;get link to next word in list
TRZ WD,700000 ;zero out the length field
JUMPE WD,DONE ;a zero link means end of list
HLRO A,SORDID(WD) ;get length this word
ASH A,-17 ;right adjust the length
HRRZ TXTPTR,SORDID(WD) ;get the pointer to the text of this word
MOVE PART1,1(TXTPTR)
MOVE PART2,2(TXTPTR)
MOVE PART3,3(TXTPTR) ;load the parts of this word into ACs
MOVE PART4,4(TXTPTR)
SUB TXTPTR,A ;advance TXTPTR to next consecutive word in TEXT
CAMGE A,[-4]
HRREI A,-4 ;prepare to compare at most 4 parts of current word
MOVEM A,LEN ;save pseudo length of this word
JRST .+2
NXTDWD: PUSHJ P,RDDICT
HLRZ FIRST,DICT(DICTWD) ;get pointer to text of dictionary word
MOVE A,LEN ;put length of current word into A
CAME PART1,WORDS(FIRST) ;compare parts until inequality or
JRST CK1 ; until no more parts left in
AOJGE A,EQUAL ; which case words must be equal
CAME PART2,WORDS+1(FIRST)
JRST CK2
AOJGE A,EQUAL
CAME PART3,WORDS+2(FIRST)
JRST CK3
AOJGE A,EQUAL
CAMN PART4,WORDS+3(FIRST)
JRST EQUAL
CK4: CAMG PART4,WORDS+3(FIRST) ;when a part is unequal, see which word is less
JRST NEXTWD ;Word not in dictionary
JRST NXTDWD ;Get next dictionary word
CK3: CAMG PART3,WORDS+2(FIRST)
JRST NEXTWD
JRST NXTDWD
CK2: CAMG PART2,WORDS+1(FIRST)
JRST NEXTWD
JRST NXTDWD
CK1: CAMG PART1,WORDS(FIRST)
JRST NEXTWD
JRST NXTDWD
;Link up keyword in story.
EQUAL: HLRZ A,DICT+1(DICTWD) ;is current dict word part of a mult key?
JUMPE A,CATEG ;no. categorize current story by dict wd
PUSH P,MLTREC ;save record nbr of current mult key
PUSH P,MLTPTR
PUSH P,DICTWD ;save current dict word
MOVE DICTWD,A ;get ptr to next word in multiple key
ADDI WD,1 ;move ptr to following word in story
MOVE PART1,1(TXTPTR) ;load the parts of the story word into ACs
MOVE PART2,2(TXTPTR)
MOVE PART3,3(TXTPTR)
MOVE PART4,4(TXTPTR)
HLRO A,SORDID(WD) ;get length of this story word
ASH A,-17 ;shift length into low order bits of AC
SUB TXTPTR,A ;move TXTPTR to the NEXT story word
CAMGE A,[-4] ;compare at most 4 parts of the story
HRREI A,-4 ; word and the dict word
MOVEM A,LEN ;save pseudo length of story word
BRO: PUSHJ P,GETMLT ;make sure the DICT rec containing the mult is in core
MOVE A,LEN ;put length of story word in AC A for counting
HLRZ FIRST,DICT(DICTWD) ;get ptr to first part of dict wd in WORDS
CAME PART1,WORDS(FIRST) ;compare story word and dict word
JRST NOTSAM
AOJGE A,EQUAL ;A=0 means we are at end of story word
CAME PART2,WORDS+1(FIRST)
JRST NOTSAM
AOJGE A,EQUAL
CAME PART3,WORDS+2(FIRST)
JRST NOTSAM
AOJGE A,EQUAL
CAMN PART4,WORDS+2(FIRST)
JRST EQUAL
NOTSAM: HRRZ DICTWD,DICT+2(DICTWD) ;story word not same as dict wd. get ptr to
JUMPN DICTWD,BRO ; mult bro. if zero, then no bro exists.
JRST EQ2
;categorize story by longest keyword that matched.
CATEG: SKIPN AVAIL,LINKS ;any slots available in LINKS file?
JRST EQ2 ;no!!
CAIL DICTWD,200
PUSHJ P,[MOVE A,GUDREC ;make sure correct mult rec is in core
JRST CHKREC]
HRRE A,DICT+1(DICTWD) ;get pointer to first slot for current word
JUMPL A,EQ2 ;is this a legal keyword?
SKIPGE B,CATNBR
JRST EQ4
CAMN DICTWD,KEYS(B) ;has this keyword already categorized story?
JRST EQ2 ;yes
SOJGE B,.-2
EQ4: AOS B,CATNBR ;prepare to save ptr to keyword entry in
CAIL B,NKEYS ; KEYS array to prevent duplication
JRST EQ2 ;no more room in KEYS array. dont use keyword
MOVEM DICTWD,KEYS(B) ;insure that this keyword won't be used again
TLO F,CATFLG+WRFLAG ;set "categorized" flag & mark DICT rec as changed
MOVE B,LINKS(AVAIL) ;remove available slot from free slot list
MOVEM B,LINKS ; and update free-slot list header
JUMPE A,EQ1 ;a zero pointer means no such slot exists
HRRM AVAIL,LINKS(A) ;store back ptr to new slot in old slot
HRLM A,LINKS(AVAIL) ;store ptr to old slot in new slot
EQ1: CAIL DICTWD,200 ;is this a mult word key?
SKIPA A,MLTPTR ;yes. get negated ptr to mult word key
MOVN A,DICPTR ;no. negate dictwd pointer for storing it
HRRM A,LINKS(AVAIL) ;store negated dict pointer in new slot
HRRM AVAIL,DICT+1(DICTWD) ;store ptr to new slot in dict entry for current word
MOVE A,LINKS+1 ;get back ptr to last slot in current story
MOVEM A,LINKS+1(AVAIL) ;store that ptr in new slot
MOVE B,UNDUN ;load ptr to current story
HRRM B,LINKS+1(AVAIL) ;store ptr to current story in new slot
HRLZM AVAIL,LINKS+1 ;update back ptr to last slot for story (new slot)
EQ2: CAMN P,INITPD ;have all multiple word entries been popped?
JRST NEXTWD ;yes
POP P,DICTWD ;no. pop next one off stack
SUBI WD,1 ; and readjust ptr to word in story
POP P,MLTPTR
POP P,GUDREC ;retrieve mult rec nbr for this mult key
TLNE F,CATFLG ;has the current keyword been categorized?
JRST EQ2 ;yes. just pop rest of mult word entries.
JRST CATEG ;no. try to categorize it now.
;Write out new versions of files.
DONE: USETO 3,@DICREC ;select the appropriate record for writing out dict
TLNE F,WRFLAG ;has the record of DICT that is in core been changed?
OUT 3,DCMD ;yes. write out the new values.
JRST .+2
UBIGERR 100 ; ;OUT UUO FAILED TO WRITE OUT RECORD OF DICT
SKIPN MLTREC ;is there a mult rec of DICT in core?
JRST DUN2 ;no
USETO 3,@MLTREC ;yes. select correct rec for writing it out
OUT 3,MCMD ;write out last mult rec that is in core
JRST .+2
UBIGERR 104 ; ;OUT UUO FAILED TO WRITE OUT LAST MULT REC OF DICT
DUN2: OPEN 10,DSK17 ;prepare to write out LINKS
UERROR 110 ; ;OPEN FAILED ON DSK
SETZM LINKSF+1
SETZM LINKSF+2
SETZM LINKSF+3
ENTER 10,LINKSF
UERROR 114 ; ;ENTER FAILED ON FILE: LINKS
OUT 10,LCMD ;write out LINKS file
JRST .+2
UERROR 120 ; ;OUT UUO FAILED TO WRITE OUT FILE: LINKS
FINISH: MOVE B,UNDUN ;get ptr to current (UNDUN story)
OPEN 6,DSK17 ;prepare to open INDEX for reading old version
UERROR 124 ; ;OPEN FAILED ON DSK
SETZM INDEXF+3
LOOKUP 6,INDEXF ;INDEX file
UERROR 130 ; ;LOOKUP FAILED ON FILE: INDEX
IN 6,XCMD ;read in entire INDEX file
JRST .+2
UERROR 134 ; ;IN UUO FAILED TO READ IN FILE: INDEX
RELEAS 6, ;old version of INDEX that was just read
TLNE F,MISSIN ;should new parameters be written out for this story?
JRST FIN3 ;no
HLLZ A,LINKS+1 ;load back ptr to last slot for current story
TLNE F,TAKEFG ;is this story a take?
HRRI A,-1 ;yes. turn on TAKE indicator for this story
MOVEM A,INDEX(B) ;store back ptr and take indicator for this story
JUMPE PREV,FIN3 ;ACs WD and PREV are the same. so if the current
HLRZ A,INDEX+2(PREV) ;IS PREV STORY A FOLLOW UP?
JUMPN A,.+2
MOVE A,PREV ;NO
HRLM A,INDEX+2(B) ;SAVE PTR TO ORIGINAL STORY
FIN1: HRRE A,INDEX(PREV) ; story is to be linked up with an earlier
JUMPLE A,FIN2 ; one, PREV will be non-zero. if the current
MOVE PREV,A ; story is not to be linked up with an
JRST FIN1 ; earlier story WD (PREV) will be zero
FIN2: HRRM A,INDEX(B) ;put whatever was in the old story's link in the new story's
HRRM B,INDEX(PREV) ;put a link to the new story in the old story's link
FIN3: ADDI B,XSIZE ;advance UNDUN
CAIL B,XLEN
MOVEI B,SPECS
MOVEM B,UNDUN ;put new value of UNDUN back into INDEX array
OUT 7,XCMD ;write out new INDEX file
JRST .+2
UERROR 140 ; ;OUT UUO FAILED TO WRITE OUT FILE: INDEX
RELEAS 10, ;LINKS file
RELEAS 3, ;DICT file
RELEAS 7, ;new version of INDEX file
TLNE F,MISSIN ;check if the story to have been catagorized was missing
UBIGERR 144 ; ;A STORY DISAPPEARED BEFORE BEING CATAGORIZED
; OUTSTR [ASCIZ / FINISHED! /]
SKIPE LINKS ;have we run out of slots in LINKS?
JRST MORE ;no
JUMPN PREV,MORE ;prev ≠ 0 means LINKS wasn't read in, so we are ok
UBIGERR 150 ; ;LINKS WAS READ IN AND THERE ARE NO MORE SLOTS
;Subroutines: RDDICT, GTDICT, PAUSE1-4, DIGEST, DONTDO, GONE.
RDDICT: SETOM CATNBR ;indicate no similar keywords used
MOVEI A,2 ;advance to next entry in dictionary by incrementing
ADDM A,DICPTR ; DICPTR and DICTWD by 2
ADDI DICTWD,2
CAIGE DICTWD,200 ;has DICTWD gone beyond the record that is in core?
POPJ P, ;no. return.
TLNN F,WRFLAG ;has the DICT record in core been changed?
JRST GTDICT ;no
USETO 3,@DICREC ;yes. select correct record for writing it out
OUT 3,DCMD ;write out the new values.
JRST .+2
UBIGERR 154 ; ;OUT UUO FAILED TO WRITE OUT ONE RECORD OF DICT
GTDICT: AOS A,DICREC ;adjust DICREC to the new record number
USETI 3,(A)
IN 3,DCMD ;read in the next record
JRST .+2
UBIGERR 160 ; ;IN UUO FAILED TO READ IN A RECORD OF DICT
TLZ F,WRFLAG ;clear the write flag
SETZ DICTWD, ;set DICTWD to point at beginning of record
POPJ P, ;return
;make sure the record needed for a mult DICT entry, as indicated by DICTWD, is in core
GETMLT: MOVE A,DICTWD
MOVNM DICTWD,MLTPTR ;save negated ptr to this mult word key
TRZ DICTWD,777600 ;zero out record part of DICTWD
ADDI DICTWD,200 ;make DICTWD point to the mult rec of DICT in core
ASH A,-7 ;calculate the number of the mult rec needed in core
ADDI A,1
CHKREC: MOVEM A,GUDREC
CAMN A,MLTREC ;is that record already in core?
POPJ P, ;yes
SKIPN MLTREC ;is any mult rec in core?
JRST GETM ;no
USETO 3,@MLTREC ;yes. select the proper rec nbr for writing it back out
OUT 3,MCMD ;write out the rec that is in core
JRST .+2
UBIGERR 164 ; ;OUT UUO FAILED TO WRITE OUT MULT REC OF DICT
GETM: MOVEM A,MLTREC ;save number of new mult rec to be in core
USETI 3,(A) ;select the correct record to be read in
IN 3,MCMD ;read in a new mult rec
POPJ P, ;return
UBIGERR 170 ; ;IN UUO FAILED TO READ IN MULT REC FROM DICT
PAUSE1: RELEAS 0,
; OUTSTR [ASCIZ / PAUSE-NEWS /]
MOVEI A,2
CALL A,[SIXBIT /SLEEP/]
JRST AGAIN1
PAUSE2: RELEAS 7,
; OUTSTR [ASCIZ / PAUSE-INDEX /]
MOVEI A,2
CALL A,[SIXBIT /SLEEP/]
JRST READ
PAUSE3: RELEAS 1,
MOVEI A,1
CALL A,[SIXBIT /SLEEP/]
JRST AGAIN3
PAUSE4: RELEAS 3,
MOVEI A,2
CALL A,[SIXBIT /SLEEP/]
JRST AGAIN4
;and now, a few kludges...
DONTDO:
DIGEST: SETZ PREV, ;inhibit linking this story with any earlier story
SETOM LINKS ;inhibit error msg about no slots in LINKS
SETZM LINKS+1 ;clear back ptr to LINKS slots for this story
JRST LINKEM ;finish up
GONE: SETOM LINKS ;inhibit error msg about no slot in LINKS
TLO F,MISSIN ;set flag indicating that this story was not found
JRST LINKEM ;finish up
;Subroutines: UUCODE.
ECMD: IOWD 1,BUF
0
EMSG: ASCIZ /DOER error #/]
ELEN←←.-EMSG
UUCODE: 0
HRRZ A,40 ;get error number
MOVE BPTR,[POINT 7,D]
SETZ D,
PUSHJ P,NXTDG
SETO A,
GETLIN A
AOJE A,DET
HLRZ A,40
CAIN A,(<UBIGERR>)
OUTSTR [ASCIZ/SUPER /]
CAIE A,(<UEXIT>) ;is this a horrendous error?
OUTSTR [ASCIZ/HORRENDOUS /] ;yes
OUTSTR EMSG
OUTSTR D
CALLI 1,12
JRST @UUCODE
DET: CALLI 0
HLRZ A,40
CAIN A,(<UEXIT>) ;is this a horrendous error?
JRST DETFIN ;no. swap in new DOER
OPEN 1,DSK17 ;yes. write message in error file
CALLI 12
SETZM ERRORF+3
LOOKUP 1,ERRORF
SETZM ERRORF+3 ;lookup failed. pretend file there with 0 words
HLRE A,ERRORF+3 ;pick up word count of error file
SETZM ERRORF+3
ENTER 1,ERRORF
JRST DETFIN
DPB A,[POINT 7,ECMD,17];put -(word count mod 200) into dump mode command
MOVN A,A ;make word count positive
LDB B,[POINT 11,A,28];get record part of count
ANDI A,177 ;get remainder
JUMPE A,PUTERR ;if no remainder, then dont read in anything
USETI 1,1(B)
IN 1,ECMD
JRST .+2
CALLI 12
PUTERR: MOVEI C,BUF(A)
HRLI C,EMSG
BLT C,BUF+ELEN-1(A) ;put error message into block to be output
MOVEM D,BUF+ELEN(A) ;put ASCIZ error number into block
MOVE C,[ASCIZ/
/]
MOVEM C,BUF+ELEN+1(A) ;put crlf after error number
MOVNI A,ELEN+2(A) ;calculate number of words to be written out
HRLM A,ECMD ; and put it negated into dump mode command
USETO 1,1(B)
OUTPUT 1,ECMD
RELEAS 1,
DETFIN: SKIPE RESTAR ;is this a restarted DOER?
CALLI 12 ;yes. dont restart again
HLRZ A,40 ;no
MOVEI B,SWAPBK
CAIE A,(<UBIGERR>) ;super horrendous error?
CALLI B,400004 ;no. swap in and start up fresh version of DOER
CALLI 12
NXTDG: IDIVI A,=8 ;convert number in AC A to octal ASCII string
PUSH P,B
SKIPE A
PUSHJ P,NXTDG
POP P,A
ADDI A,60
IDPB A,BPTR
POPJ P,
;Interrupt level module: INTRPT, CHGNAM.
INTRPT: MOVE A,JOBCNI
JFFO A,.+1
CAIN A+1,=19 ;was it an interrupt to set the job name
JRST CHGNAM ;yes. do it.
MOVEM A+1,SVINTR# ;save indicator of the cause of interrupt
CALL [SIXBIT /UWAIT/]
JRST@ 2,[.+1] ;no. get out of user-iot.
CALL [SIXBIT /DEBREAK/]
MOVE A,SVINTR
CAIE A,=9 ;was the interrupt for a parity error?
UBIGERR 174 ; ;UNKNOWN INTERRUPT OCCURRED
UEXIT 200 ; ;PARITY ERROR
CHGNAM: SETZ A, ;zero out job name
CALL A,[SIXBIT /SETNAM/]
SETOM NRDOER ;initialize indicator to one other doer
MOVE A,NAME
CALL A,[SIXBIT /NAMEIN/]
JRST .+2 ;zero or multiple doers exist
CALL [SIXBIT /DISMIS/] ;exactly one other doer exists
SETZM NRDOER ;set indicator to multiple doers
CAIE A,1 ;check error code of NAMEIN
CALL [SIXBIT /DISMIS/] ;multiple doers exist
AOS NRDOER ;set indicator to no other doers
MOVE A,NAME ;set job name
CALL A,[SIXBIT /SETNAM/]
MOVEI A,200000
CALL A,[SIXBIT /INTACM/] ;disable further pdl ov interrupts
CALL [SIXBIT /DISMIS/]
END DOER